//
//  ConTotalMsg.swift
//  Trans
//
//  Created by zcj on 2025/2/20.
//  description:保存链接信息的类，主要是为了保存是否进行了重连的数据，以及保存了重连期间的请求。
//  side为0时，代表为client。否则为listen

import Foundation
import NetAction
class ConContainerMsg{
    //connection对应的请求类型
    var clientTypeDic:Dictionary<String,Set<UINT32>> = [:]
    var listenTypeDic:Dictionary<String,Set<UINT32>> = [:]
    
    //connection对应的请求
    var clientTaskDic:Dictionary<String,Array<BaseData>> = [:]
    var listenTaskDic:Dictionary<String,Array<BaseData>> = [:]
    
    static let shared:ConContainerMsg = ConContainerMsg()
    
    func addConnection(ip:String, side:TERMINALSIDE){
        //根据side，与ip判断是否已经开始重连
        if side == .CLIENT && clientTaskDic.keys.contains(ip) {
            return;
        }else if side == .LISTENER && listenTaskDic.keys.contains(ip){
            return;
        }else{
            if side == .CLIENT{
                clientTaskDic[ip] = []
            }else{
                listenTaskDic[ip] = []
            }
        }
        
    }
    
    func removeConnection(ip:String, side:TERMINALSIDE){
        if side == .CLIENT{
            clientTaskDic.removeValue(forKey: ip)
            clientTypeDic.removeValue(forKey: ip)
        }else{
            listenTaskDic.removeValue(forKey: ip)
            listenTypeDic.removeValue(forKey: ip)
        }
    }
    
    func addTask(ip:String,side:TERMINALSIDE,task:BaseData){
       
        if markOnceType(ip: ip, side: side, task: task){
            return
        }
        var arr:Array<BaseData> = []
        if side == .CLIENT{
            if clientTaskDic[ip] == nil{
                clientTaskDic[ip] = []
            }
            arr = clientTaskDic[ip]!
        }else{
            if listenTaskDic[ip] == nil{
                listenTaskDic[ip] = []
            }
            arr = listenTaskDic[ip]!
        }
        if !arr.contains(task),task.getType() != RECONNECT{
            arr.append(task)
        }
    }
    
   
    
    func initByIp(ip:String,side:TERMINALSIDE){
        if side == .CLIENT
        {
            if clientTaskDic[ip] == nil{
                clientTaskDic[ip] = []
            }
            if clientTypeDic[ip] == nil{
                clientTypeDic[ip] = []
            }
            
        }
        else
        {
            if listenTaskDic[ip] == nil{
                listenTaskDic[ip] = []
            }
            if listenTypeDic[ip] == nil{
                listenTypeDic[ip] = []
            }
        }
    }
    //判断是否已经发送过该请求
    func canBeAdd(ip:String,type:UINT32,side:TERMINALSIDE) -> Bool{
        
        let confirmTypeArr = OnceTimeReqType()
        var currTypeSet = Set<UINT32>()
        if side == .CLIENT{
            currTypeSet = clientTypeDic[ip] ?? []
        }else{
            currTypeSet = listenTypeDic[ip] ?? []
        }
        if currTypeSet.contains(type) && confirmTypeArr.contains(type){
            return false
        }
        return true
    }
    
    func performTask(ip:String,side:TERMINALSIDE,conid:ConId){
        if side == .CLIENT {
            if let arr = clientTaskDic[ip]{
                arr.forEach { baseData in
                    //client addtask
                    TCPClientManager.shared.clientDic[conid]?.addTask(data: baseData)
                }
            }
            clientTaskDic.removeValue(forKey: ip)
            clientTypeDic.removeValue(forKey: ip)
        }else{
            if let arr = listenTaskDic[ip],let con = kzListener.conDic[conid]?.con {
                arr.forEach { baseData in
                    //client addtask
                    let pkgData = BaseData.pkgData(obj: baseData)
                    con.send(content: pkgData, completion: .contentProcessed({ error in
                        if error != nil{
                            error_log("listenTaskDic send failed,type: \(baseData.getType())")
                        }
                    }))
                }
            }
            listenTaskDic.removeValue(forKey: ip)
            listenTypeDic.removeValue(forKey: ip)
        }
    }
    
    //如果时这里的就只发送一次，因此不加入taskdic中
    func markOnceType(ip:String,side:TERMINALSIDE,task:BaseData) -> Bool{
        if(task.getType() == RECONNECT){
            if side == .CLIENT{
                if clientTypeDic[ip] == nil{
                    clientTypeDic[ip] = []
                }
                clientTypeDic[ip]?.insert(task.getType())
            }else{
                if listenTypeDic[ip] == nil{
                    listenTypeDic[ip] = []
                }
                listenTypeDic[ip]?.insert(task.getType())
            }
            return true
        }
        return false
    }
    
    
}
